package main

import (
	"fmt"
	"reflect"
	"strings"
)

func main() {
	ms := new(struct1)
	ms.i1 = 10
	ms.f1 = 3.14
	ms.s1 = "Chris"
	fmt.Printf("The int is :%d\n", ms.i1)
	fmt.Printf("The float is :%f\n", ms.f1)
	fmt.Printf("The string is :%s\n", ms.s1)
	fmt.Printf("The struct is :%v\n", ms)
	var v struct1
	var p *struct1
	fmt.Printf("The struct is :%v\n", v)
	fmt.Printf("The struct is :%v\n", p)
	//初始化方式1
	intr := Interval{1, 2}
	//初始化方式2
	intr2 := Interval{start: 1, end: 2}
	//初始化方式3
	intr3 := Interval{end: 2}
	fmt.Printf("The struct1 is :%v\n", intr)
	fmt.Printf("The struct2 is :%v\n", intr2)
	fmt.Printf("The struct3 is :%v\n", intr3)
	//struct 值类型
	var pers1 Person
	pers1.firstName = "Chris"
	pers1.lastName = "Lee"
	upPerson(&pers1)
	fmt.Printf("The person is :%v,%v\n", pers1.firstName, pers1.lastName)
	//struct 指针类型
	pers2 := new(Person)
	pers2.firstName = "Chris"
	pers2.lastName = "Lee"
	(*pers2).lastName = "Lee1"
	upPerson(pers2)
	fmt.Printf("The person is :%v,%v\n", pers2.firstName, pers2.lastName)
	//struct 引用类型
	pers3 := &Person{"Chris", "Lee"}
	upPerson(pers3)
	fmt.Printf("The person is :%v,%v\n", pers3.firstName, pers3.lastName)
	//带标签的结构体
	tt := TagType{true, "Go", 7}
	for i := 0; i < 3; i++ {
		refTag(tt, i)
	}

}

// 结构体和它所包含的数据在内存中是以连续块的形式存在的
type struct1 struct {
	i1 int
	f1 float64
	s1 string
}

// 时间间隔
type Interval struct {
	start int
	end   int
}

type Person struct {
	firstName string
	lastName  string
}

func upPerson(p *Person) {
	p.firstName = strings.ToUpper(p.firstName)
	p.lastName = strings.ToUpper(p.lastName)
}

// 链表
type Node struct {
	data float64
	su   *Node
}

// 类型别名
type NodeAlias = Node

// 双向链表
type DNode struct {
	pr   *Node
	data float64
	su   *Node
}

// 使用工厂方法创建结构体实例
type File struct {
	fd   int    //文件描述符
	name string // 文件名
}

// 对应工厂方法
func NewFile(fd int, name string) *File {
	if fd < 0 {
		return nil
	}
	return &File{fd, name}
}

// 带标签的结构体
type TagType struct {
	field1 bool   "hahaha"
	field2 string "the name of the thing"
	field3 int    "how much"
}

func refTag(tt TagType, ix int) {
	ttType := reflect.TypeOf(tt)
	ixField := ttType.Field(ix)
	fmt.Printf("Field name:%s\n", ixField.Tag)
}
